package com.szzg10.webservice.chapter4;

import java.io.ByteArrayInputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

public class DispatchClientTS {

	public static void main(String[] args) throws URISyntaxException, TransformerFactoryConfigurationError, TransformerException, XPathExpressionException {
		new DispatchClientTS().doIt();
	}
	
	private void doIt() throws URISyntaxException, TransformerFactoryConfigurationError, TransformerException, XPathExpressionException {
		URI uri = new URI("http://chapter1.webservice.szzg10.com/");
		
		QName service_name = new QName("tns", uri.toString());
		QName port_name = new QName("tsPort", uri.toString());
		String endpoint = "http://localhost:9876/ts";
		
		Service service = Service.create(service_name);
		service.addPort(port_name, HTTPBinding.HTTP_BINDING, endpoint);
		
		Dispatch<Source> dispatch = service.createDispatch(port_name, Source.class, Service.Mode.PAYLOAD);
		
		String text = "<?xml version='1.0' encoding='UTF-8'?>"
				+ "<S:Envelope xmlns:S='http://schemas.xmlsoap.org/soap/envelope/'><S:Body><ns2:getTimeAsString xmlns:ns2='http://chapter1.webservice.szzg10.com/'/></S:Body></S:Envelope>";
		
		invoke(dispatch, uri.toString(), text);
	}
	
	private void invoke(Dispatch<Source> dispatch, String uri, String text)
			throws TransformerFactoryConfigurationError, TransformerException, XPathExpressionException {
		Map<String, Object> requestContext = dispatch.getRequestContext();
		requestContext.put(MessageContext.HTTP_REQUEST_METHOD, "POST");
		
		Source result = dispatch.invoke(toStream(text));
		printResult(result, uri);
	}
	
	private Source toStream(String text) {
		ByteArrayInputStream in = new ByteArrayInputStream(text.getBytes());
		return new StreamSource(in);
	}
	
	private void printResult(Source source, final String uri) throws TransformerFactoryConfigurationError, TransformerException, XPathExpressionException {
		DOMResult domResult = new DOMResult();
		
		Transformer transformer = TransformerFactory.newInstance().newTransformer();
		transformer.transform(source, domResult);
		
		XPath xPath = XPathFactory.newInstance().newXPath();
		xPath.setNamespaceContext(new NamespaceContext() {
			
			@Override
			public Iterator getPrefixes(String namespaceURI) {
				return null;
			}
			
			@Override
			public String getPrefix(String namespaceURI) {
				return uri;
			}
			
			@Override
			public String getNamespaceURI(String prefix) {
				return uri;
			}
		});
		
		String result = xPath.evaluate("//return", domResult.getNode());
		System.out.println(result);
	}
}
